﻿namespace com.stifel.Global
{
    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Reflection;
    using System.Xml;

    using com.stifel.Extensions.AssemblyExtensions;
    using com.stifel.Extensions.SharePointExtensions;
    using com.stifel.Extensions.SymbolExtensions;
    using com.stifel.GlobalDao;
    using com.stifel.SharePoint;

    using Microsoft.SharePoint;

    public class Timezone_Definition : BaseDefinition
    {
        #region Fields

        const string LOOKUPSITECOLUMNS = "Timezone.Lookup.fields.xml";
        const string SITECOLUMNS = "Timezone.fields.xml";

        #endregion Fields

        #region Constructors

        public Timezone_Definition( SPFeatureReceiverProperties spFeatureReceiverProperties )
            : base(spFeatureReceiverProperties)
        {
        }

        ~Timezone_Definition( )
        {
            Dispose( false );
        }

        #endregion Constructors

        #region Methods

        public override void Create( )
        {
            base.Create( );
            CreateSiteColumns( getFieldDefinitionsAsXml( SITECOLUMNS ) );
            CreateContentType( getContentTypeDefn( ) );
            CreateList( getListDefn( ) );
            CreateSiteColumns( getFieldDefinitionsAsXml( LOOKUPSITECOLUMNS ) );
            loadList( );
        }

        public override void Delete( )
        {
            base.Delete( );
            DeleteList( getListDefn( ), true );
            DeleteContentType( getContentTypeDefn( ) );
            DeleteSiteColumns( getFieldDefinitionsAsXml( LOOKUPSITECOLUMNS ) );
            DeleteSiteColumns( getFieldDefinitionsAsXml( SITECOLUMNS ) );
        }

        ContentTypeDefn getContentTypeDefn( )
        {
            Timezone c = null;
            return new ContentTypeDefn
            {
                Name = Item.GetContentTypeName<Timezone>( ),
                ContentTypeId = Item.GetContentTypeId<Timezone>( ),
                Group = "General Content Types",
                Description = "Defines a time zone.",
                Fields = new FieldDefn[ ] {
                    new FieldDefn {
                        Name = Item.GetColumnName<Timezone>( c.GetPropertySymbol( o => o.TimeZone ))
                    },
                    new FieldDefn {
                        Name = Item.GetColumnName<Timezone>( c.GetPropertySymbol( o => o.TimeZoneID ) ),
                        Required = true
                    },
                    new FieldDefn {
                        Name = Item.GetColumnName<Timezone>( c.GetPropertySymbol( o=> o.TimeZoneActive ) )
                    }
                }.Distinct( ).ToList( ),
            };
        }

        XmlNodeList getFieldDefinitionsAsXml( string resource )
        {
            XmlNodeList fields = null;
            string s = Assembly.GetExecutingAssembly( ).GetFullyQualifiedManifestResourceName( resource );
            string xml = Assembly.GetExecutingAssembly( ).GetManifestResourceAsString( s );
            if ( !string.IsNullOrEmpty( xml ) )
            {
                XmlDocument d = new XmlDocument( );
                d.LoadXml( xml );
                XmlNode n = d.SelectSingleNode( "Fields" );
                fields = n.SelectNodes( "Field" );
            }
            return fields;
        }

        ListDefn getListDefn( )
        {
            return new ListDefn
            {
                RootFolderName = TimezoneDao.ListName,
                Title = "Time Zones",
                Description = "Contains the world's time zones.",
                ContentTypes = new string[ ]{
                    Item.GetContentTypeName<Timezone>( )
                }.ToList( )
            };
        }

        void loadList( )
        {
            TimezoneDao dao = new TimezoneDao( Properties.GetWeb( ).Url );
            dao.Clear( );
            ReadOnlyCollection<TimeZoneInfo> tzs = TimeZoneInfo.GetSystemTimeZones( );
            foreach ( TimeZoneInfo tz in tzs )
            {
                Timezone t = new Timezone
                {
                    TimeZoneID = tz.Id,
                    Title = string.Format( "{0} {1}", tz.Id, tz.DisplayName )
                };
                // if state, possession, or territory within the USPS abbreviation set, then make the corresponding timezone active
                switch ( tz.Id )
                {
                    case TimeZoneInfoConstants.AlaskanStandardTime:
                    case TimeZoneInfoConstants.AtlanticStandardTime:
                    case TimeZoneInfoConstants.CentralPacificStandardTime:
                    case TimeZoneInfoConstants.CentralStandardTime:
                    case TimeZoneInfoConstants.EasternStandardTime:
                    case TimeZoneInfoConstants.FijiStandardTime:
                    case TimeZoneInfoConstants.HawaiianStandardTime:
                    case TimeZoneInfoConstants.MountainStandardTime:
                    case TimeZoneInfoConstants.NorthAsiaEastStandardTime:
                    case TimeZoneInfoConstants.PacificStandardTime:
                    case TimeZoneInfoConstants.USEasternStandardTime:
                    case TimeZoneInfoConstants.USMountainStandardTime:
                    case TimeZoneInfoConstants.UTCminus11:
                    case TimeZoneInfoConstants.WestPacificStandardTime:
                        t.TimeZoneActive = true;
                        break;
                    default:
                        t.TimeZoneActive = false;
                        break;
                }
                dao.Add( t );
            }
        }

        #endregion Methods
    }
}